#pragma once

#include <iostream>
#include <mutex>
#include <thread>
#include <condition_variable>
#include <functional>

#include "serial/serial.h"


namespace alive
{

namespace chassis_serial
{

static const int DEFAULT_RATE = 115200;
static const std::string SERIAL_NAME = "/dev/serial_usb";

typedef std::function<void (std::vector<uint8_t> & data)> PROCESS_CALLBACK;
class ChassisSerial
{
public:
    ChassisSerial(const std::string serialName = SERIAL_NAME, const int rate = DEFAULT_RATE);
    ChassisSerial(const ChassisSerial&) = delete;
    ChassisSerial& operator=(const ChassisSerial&) = delete;
    ~ChassisSerial();
    

    int sendData(u_int8_t* data, size_t len);
    void recieveData();
    void processData();
    bool initSerial();
    void starRecv();
    void starProcess();
    void stopRecv();
    void stopProcess();
    void registerCallback(PROCESS_CALLBACK call){
        if(!process_call_)
            process_call_ = call;
    };
    
private:
    

private:
    std::string serial_name_;
    int serial_rate_;
    serial::Serial serial_;
    std::vector<uint8_t> buf_;
    bool recv_flag_, process_flag_;
    std::mutex buf_mutex_;
    std::condition_variable condition_var_;
    PROCESS_CALLBACK process_call_;
    std::shared_ptr<std::thread> recv_thr_, process_thr_;


};


}//namespace serial
}//namespace alive
